﻿using LogisticsTrackingWebApi_V3.Models;
using LogisticsTrackingWebApi_V3.Services;
using LogisticsTrackingWebApi_V3.ServicesImpl.Decorators;
using Microsoft.Extensions.Caching.Memory;

namespace LogisticsTrackingWebApi_V3.ServicesImpl
{

    /// <summary>
    /// 物流服务工厂 - 负责创建和管理物流查询服务实例
    /// </summary>
    public class LogisticsProviderFactory
    {
        private readonly IMemoryCache _cache;
        private readonly ILogger<LoggingDecorator> _logger;
        private readonly IEnumerable<ILogisticsProvider> _originalProviders;
        private readonly Dictionary<string, ILogisticsProvider> _decoratedProviders = new();

        public LogisticsProviderFactory(
            IMemoryCache cache,
            ILogger<LoggingDecorator> logger,
            IEnumerable<ILogisticsProvider> originalProviders)
        {
            _cache = cache;
            _logger = logger;
            _originalProviders = originalProviders;

            // 初始化装饰后的提供者
            InitializeDecoratedProviders();
        }

        /// <summary>
        /// 初始化所有装饰后的物流查询提供者
        /// </summary>
        private void InitializeDecoratedProviders()
        {
            foreach (var provider in _originalProviders)
            {
                // 装饰器组合：原始提供者 → 缓存装饰器 → 日志装饰器
                var decoratedProvider = new LoggingDecorator(
                    new CachingDecorator(provider, _cache),
                    _logger
                );

                _decoratedProviders[provider.CompanyCode] = decoratedProvider;
            }
        }

        /// <summary>
        /// 根据公司代码获取装饰后的物流查询提供者
        /// </summary>
        public ILogisticsProvider GetProvider(string companyCode)
        {
            if (string.IsNullOrWhiteSpace(companyCode))
                throw new ArgumentException("公司代码不能为空");

            if (_decoratedProviders.TryGetValue(companyCode, out var provider))
                return provider;

            throw new KeyNotFoundException($"不支持的物流公司代码：{companyCode}");
        }

        /// <summary>
        /// 获取所有支持的物流公司
        /// </summary>
        public IEnumerable<LogisticsCompany> GetSupportedCompanies()
        {
            return _decoratedProviders.Values.Select(p => new LogisticsCompany
            {
                Code = p.CompanyCode,
                Name = p.CompanyName
            });
        }

        /// <summary>
        /// 尝试根据运单号猜测可能的物流提供者
        /// </summary>
        public ILogisticsProvider? GuessProvider(string trackingNumber)
        {
            if (string.IsNullOrWhiteSpace(trackingNumber))
                return null;

            return _decoratedProviders.Values
                .FirstOrDefault(p => p.MatchTrackingNumber(trackingNumber));
        }
    }

}
